// GetWindowInfo.cpp: implementation of the CGetWindowInfo class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "MyWindow.h"
#include "GetWindowInfo.h"

#include "public.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////


CGetWindowInfo::CGetWindowInfo()
{

}

CGetWindowInfo::~CGetWindowInfo()
{

}

int CGetWindowInfo::GetWindowFromCursorInfo()
{
	int nResult = false;
	int nRetCode = false;

	static int n = 0;

	HWND hWnd = NULL;

	nRetCode = GetWindowFromCursorPos(&hWnd);
	ZOU_PROCESS_ERROR(nRetCode);
	ZOU_PROCESS_SUCCESS(hWnd == m_WinInfo.hWnd);

	RedrawWindowFrame(m_WinInfo.hWnd);

	nRetCode = FillWindowInfo(hWnd, m_WinInfo);
	ZOU_PROCESS_ERROR(nRetCode);

	nRetCode = DrawWindowFrame(m_WinInfo.hWnd);
	ZOU_PROCESS_ERROR(nRetCode);

Exit1:
	nResult = true;

Exit0:
	return nResult;
}

int CGetWindowInfo::EraseLastWindow()
{
	int nResult = false;
	int nRetCode = false;

	ZOU_PROCESS_ERROR(IsWindow(m_WinInfo.hWnd));

	nRetCode = RedrawWindowFrame(m_WinInfo.hWnd);
	ZOU_PROCESS_ERROR(nRetCode);

	nResult = true;
Exit0:
	return nResult;
}

int CGetWindowInfo::FillWindowInfo(HWND hWnd, CZWinInfo &WinInfo)
{
	int nResult = false;
	int nRetCode = false;

	char szClassName[MAX_PATH] = {0};

	ZOU_PROCESS_ERROR(IsWindow(hWnd));

	WinInfo.hWnd = hWnd;

	SendMessage(hWnd, WM_GETTEXT, BUFFER_SIZE, (LPARAM)WinInfo.szWindowCaption);

	nRetCode = ::GetClassName(
		WinInfo.hWnd, 
		WinInfo.szWindowClassName, 
		BUFFER_SIZE
		);
	ZOU_PROCESS_ERROR(nRetCode);

	nResult = true;
Exit0:
	return nResult;
}



int CGetWindowInfo::GetWindowFromCursorPos(HWND *phWnd)
{
	int nResult = false;
	int nRetCode = false;

	static POINT ptCursorPos = {0};

	HWND hWnd = NULL;

	ZOU_PROCESS_ERROR(GetCursorPos(&ptCursorPos));

	nRetCode = GetRealWindow(phWnd, ptCursorPos);
	ZOU_PROCESS_ERROR(nRetCode);

	nResult = true;
Exit0:
	return nResult;
}

int CGetWindowInfo::RedrawWindowFrame(HWND hWnd)
{
	int nResult = false;
	int nRetCode = false;

	CRgn rgMaxFrameRgn;
	CRgn rgMinFrameRgn;
	CRgn rgInvalidateFrameRgn;

	CRect rtWinRect;

	CWnd *pWndParent = NULL;
	CDC *pDC = NULL;

	HWND hWndParent = NULL;

	ZOU_PROCESS_ERROR(IsWindow(hWnd));

	::GetWindowRect(hWnd, &rtWinRect);

	::RedrawWindow(hWnd,
		NULL, NULL, 
		RDW_INTERNALPAINT | RDW_INVALIDATE | RDW_ERASENOW | 
		RDW_UPDATENOW | RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN
		);

	hWndParent = GetParent(hWnd);

	if(hWndParent)
	{
		::RedrawWindow(
			hWndParent,
			NULL, NULL, 
			RDW_INTERNALPAINT | RDW_INVALIDATE | RDW_ERASENOW | 
			RDW_UPDATENOW | RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN
			);
	};

	nResult = true;
Exit0:
	return nResult;
}

int CGetWindowInfo::DrawWindowFrame(HWND hWnd)
{
	int nResult = false;
	int nRetCode = false;

	static CRect	rtWinRect;
	static CDC		DC;	
	static CPen     pen(PS_SOLID, 3, RGB(255,0,0));
	static CPen		*pOldPen = NULL;
	static HDC		hDC = NULL;


	ZOU_PROCESS_ERROR(IsWindow(hWnd));

	::GetWindowRect(hWnd, &rtWinRect);

	hDC = ::GetWindowDC(hWnd);
	ZOU_PROCESS_ERROR(hDC);

	DC.Attach(hDC);

	pOldPen = DC.SelectObject(&pen);

	DC.MoveTo(0, 0);
	DC.LineTo(rtWinRect.Width(), 0);
	DC.LineTo(rtWinRect.Width(), rtWinRect.Height());
	DC.LineTo(0, rtWinRect.Height());
	DC.LineTo(0, 0);

	DC.SelectObject(pOldPen);

	DC.DeleteDC();

	::ReleaseDC(hWnd, hDC);

	nResult = false;
Exit0:
	return nResult;
}

void CGetWindowInfo::Reset()
{
	m_WinInfo.szWindowCaption[0] = '0';
	m_WinInfo.szWindowClassName[0] = '0';

	m_WinInfo.hWnd = NULL;
}

int CGetWindowInfo::GetRealWindow(HWND *phWnd, POINT ptPoint)
{
	int nResult = false;
	int nRetCode = false;

	HWND hWndTop = NULL;
	HWND hWndChild = NULL;

	POINT ptCooChild = {0};
	LONG lWindowStyle = 0;

	hWndTop = ::WindowFromPoint(ptPoint);
	ZOU_PROCESS_ERROR(hWndTop);

	ptCooChild = ptPoint;

	lWindowStyle = GetWindowLong(hWndTop, GWL_STYLE);

	if(
		!GetParent(hWndTop) || 
		GetDesktopWindow() == GetParent(hWndTop) ||
		!(lWindowStyle & WS_CHILDWINDOW)
		)
	{
		*phWnd = hWndTop;
	}
	else
	{
		*phWnd = GetParent(hWndTop);
	}

	::ScreenToClient(*phWnd, &ptCooChild);

	while (TRUE)
	{
		hWndChild = RealChildWindowFromPoint(*phWnd, ptCooChild);

		if (hWndChild && (hWndChild != *phWnd))
			*phWnd = hWndChild;
		else
			break;
	}


	nResult = true;
Exit0:
	return nResult;
}


int CGetWindowInfo::GetControlText(char *pszText, int nSize, HWND hWndControl)
{
	int nResult = false;
	int nRetCode = false;

	ZOU_PROCESS_ERROR(pszText);
	ZOU_PROCESS_ERROR(IsWindow(hWndControl));

	//nRetCode = GetClassName(hWndControl, )

	nResult = true;
Exit0:
	return nResult;
}
